package it.okkam.geosparql;

import it.okkam.strutturedati.ExtentCcc;
import it.okkam.strutturedati.ParticellaCatastale;
import it.okkam.strutturedati.Punto;
import it.okkam.strutturedati.Vertice;
import it.okkam.utility.UtilityQuery;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.tdb.TDBFactory;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;

public class GeoGetSetParticelle {
public static HashMap<String,List<ParticellaCatastale>> getParticelle (HashMap<String,List<ExtentCcc>> in){
	UtilityQuery ut = new UtilityQuery();
	GeoStringQuery geoSt = new GeoStringQuery();
	GeoGetSetParticelle geo = new GeoGetSetParticelle();
	List<Set<ParticellaCatastale>> listaPC = new ArrayList<Set<ParticellaCatastale>>();
	String grafoCambiamenti = "http://www.okkam.org/provinciale/cambiamenti";
	Dataset dsProvinciale = TDBFactory.assembleDataset("/home/okkam/Nicola/assemblers/provinciale-assembler.ttl");
	Model modelCambiamenti = dsProvinciale.getNamedModel(grafoCambiamenti);	
	Iterator iter = in.keySet().iterator();
	while (iter.hasNext()){
		List<ExtentCcc> listExt = new ArrayList<ExtentCcc>();
		String id = (String)iter.next();
		listExt = in.get(id);
		Iterator it = listExt.iterator();
		while (it.hasNext()){
			ExtentCcc extCcc = new ExtentCcc();
			extCcc = (ExtentCcc)it.next();
			String ccc = extCcc.getCcc();
			// launch query to get particella info
			Set<ParticellaCatastale> setParticelleC = new HashSet<ParticellaCatastale>();
			String queryString = geoSt.getStringQueryInfo(extCcc);
			System.out.println();
			System.out.println(queryString);
			String grafo = "http://www.okkam.org/"+ut.getComune(ccc)+"/particelle";
			Dataset ds = TDBFactory.assembleDataset("/home/okkam/Nicola/assemblers/"+ut.getComune(ccc)+"-assembler.ttl");
			Model model = ds.getNamedModel(grafo);	
			com.hp.hpl.jena.query.Query query = QueryFactory.create(queryString);
			QueryExecution qexec = QueryExecutionFactory.create(query, model);
	        ResultSet results = qexec.execSelect();
			
			//Geometry geomPart = geo.getGeometriaPartFromResult(results);
			Polygon polyPart = geo.getPolygonPartFromResult(results);
	        
			// launch query geomtri camb
	        Polygon polyCamb = geo.getIDPolygon(id, modelCambiamenti);
			//Geometry geomCamb = geo.getIDGeometry(id, modelCambiamenti);
			// intersect
			if (polyCamb.intersects(polyPart)){
				System.out.println("woooow");
				 setParticelleC = geo.getParticellaFromResult(results);
				listaPC.add(setParticelleC);
			}
			System.out.println(listaPC.size());
			
			
			/*if (geomPart.intersects(geomCamb)){
				
			}*/
			
			
		}
	}
	
	
	
	return null;
}

private Set<ParticellaCatastale> getParticellaFromResult(ResultSet results) {
	// TODO Auto-generated method stub
	Set<ParticellaCatastale> set = new HashSet<ParticellaCatastale>();
	for (; results.hasNext();) {
		UtilityQuery utq = new UtilityQuery();
		ParticellaCatastale p = new ParticellaCatastale();
    	QuerySolution record = results.next();
    	String ccc = record.get("ccc").toString();
    	String comune = utq.getComune(ccc);
    	
    	p.setCodiceComune(ccc);    	
    	p.setComune(comune);
    	p.setNumero(record.get("numero").toString());
    	p.setEdificialeFondiaria(record.get("edificialeFondiaria").toString());
    	p.setTipologia(record.get("lat").toString());
    	
    	if (record.get("denominatore")!=null){
    		p.setDenominatore(record.get("denominatore").toString());}
    	if (record.get("nPert")!=null){
    		p.setNumeroPertinenza(record.get("nPert").toString());}
    	set.add(p);
	}
	return set;
}

private Geometry getGeometriaPartFromResult(ResultSet results) {
	// TODO Auto-generated method stub
	UtilityQuery ut = new UtilityQuery();
	List<Vertice> listaV = new ArrayList<Vertice>();
	for (; results.hasNext();) {
		Vertice v = new Vertice();
    	QuerySolution record = results.next();
    	int cardinalita = Integer.parseInt(record.get("ordine").toString());
    	v.setCardinalita(cardinalita);
    	String puntoLa = record.get("puntoLat").toString();
    	String puntoLo = record.get("puntoLong").toString();
    	String latStr =ut.getCoordinata(puntoLa);
    	String longStr = ut.getCoordinata(puntoLo);    	
    	Double lat = Double.parseDouble(latStr);
    	Double long_ = Double.parseDouble(longStr);
    	Punto p = new Punto();
    	p.setX(lat);
    	p.setY(long_);
    	v.setVertice(p);
    	listaV.add(v);
	}
	String lineString = ut.getStringGeometryPoligono(listaV);
	Geometry geometria = null;
     try {
			geometria = new WKTReader().read(lineString);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	return geometria;
}
private Polygon getPolygonPartFromResult(ResultSet results) {
	// TODO Auto-generated method stub
	UtilityQuery ut = new UtilityQuery();
	List<Vertice> listaV = new ArrayList<Vertice>();
	for (; results.hasNext();) {
		Vertice v = new Vertice();
    	QuerySolution record = results.next();
    	int cardinalita = Integer.parseInt(record.get("ordine").toString());
    	v.setCardinalita(cardinalita);
    	String puntoLa = record.get("puntoLat").toString();
    	String puntoLo = record.get("puntoLong").toString();
    	String latStr =ut.getCoordinata(puntoLa);
    	String longStr = ut.getCoordinata(puntoLo);    	
    	Double lat = Double.parseDouble(latStr);
    	Double long_ = Double.parseDouble(longStr);
    	Punto p = new Punto();
    	p.setX(lat);
    	p.setY(long_);
    	v.setVertice(p);
    	listaV.add(v);
	}
	String lineString = ut.getStringGeometryPoligono(listaV);
	Coordinate[] listacoord= ut.getListCoordVertici(listaV);
	GeometryFactory fact = new GeometryFactory();
	LinearRing linear = new GeometryFactory().createLinearRing(listacoord);
	Polygon poly = new Polygon(linear, null, fact);
	return poly ;
}



private static Geometry getIDGeometry (String id, Model model){
	GeoGetExtentParticelleCandidate geoPart = new GeoGetExtentParticelleCandidate();
	Geometry geometria =  geoPart.getGeometriaCambiamento(id,model);
	return geometria;
}

private static Polygon getIDPolygon (String id, Model model){
	GeoGetExtentParticelleCandidate geoPart = new GeoGetExtentParticelleCandidate();
	Polygon poly =  geoPart.getPolyCambiamento(id, model);
	return poly;
}
}

